home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / misc1 / iv26_w30.zip / SOURCES / GRAPHIC / LINES.C < prev    next >
C/C++ Source or Header  |  1992-01-10  |  10KB  |  366 lines

  1. /*
  2.  * Copyright (c) 1987, 1988, 1989 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and its
  5.  * documentation for any purpose is hereby granted without fee, provided
  6.  * that the above copyright notice appear in all copies and that both that
  7.  * copyright notice and this permission notice appear in supporting
  8.  * documentation, and that the name of Stanford not be used in advertising or
  9.  * publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.  Stanford makes no representations about
  11.  * the suitability of this software for any purpose.  It is provided "as is"
  12.  * without express or implied warranty.
  13.  *
  14.  * STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  19.  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  20.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21.  */
  22.  
  23. /*
  24.  * Implementation of Points, Lines, and MultiLines, objects derived from
  25.  * Graphic.
  26.  */
  27.  
  28. #include <InterViews/Graphic/grclasses.h>
  29. #include <InterViews/Graphic/lines.h>
  30. #include <InterViews/Graphic/util.h>
  31.  
  32. boolean Point::read (PFile* f) {
  33.     return Graphic::read(f) && brush.Read(f) && f->Read(x) && f->Read(y);
  34. }
  35.  
  36. boolean Point::write (PFile* f) {
  37.     return Graphic::write(f) && brush.Write(f) && f->Write(x) && f->Write(y);
  38. }
  39.  
  40. void Point::draw (Canvas* c, Graphic* gs) {
  41.     if (gs->GetBrush()->Width() != NO_WIDTH) {
  42.     update(gs);
  43.     pPoint(c, x, y);
  44.     }
  45. }
  46.  
  47. ClassId Point::GetClassId () { return _POINT; }
  48. boolean Point::IsA (ClassId id) { return _POINT == id || Graphic::IsA(id); }
  49. Point::Point () {}
  50.  
  51. Point::Point (Coord x, Coord y, Graphic* gr) : Graphic (gr) {
  52.     if (gr == nil) {
  53.     SetBrush(nil);
  54.     } else {
  55.     SetBrush(gr->GetBrush());
  56.     }
  57.     this->x = x; 
  58.     this->y = y;
  59. }
  60.  
  61. Graphic* Point::Copy () { return new Point(x, y, this); }
  62.  
  63. void Point::GetOriginal (Coord& x, Coord& y) {
  64.     x = this->x;
  65.     y = this->y;
  66. }
  67.  
  68. void Point::getExtent (
  69.     float& l, float& b, float& cx, float& cy, float& tol, Graphic* gs
  70. ) {
  71.     float width;
  72.  
  73.     width = float(gs->GetBrush()->Width());
  74.     tol = (width > 1) ? width / 2 : 0;
  75.     transform(float(x), float(y), cx, cy, gs);
  76.     l = cx;
  77.     b = cy;
  78. }
  79.  
  80. boolean Point::contains (PointObj& po, Graphic* gs) {
  81.     PointObj pt (&po);
  82.     invTransform(pt.x, pt.y, gs);
  83.     return (pt.x == x) && (pt.y == y);
  84. }
  85.  
  86. boolean Point::intersects (BoxObj& b, Graphic* gs) {
  87.     PointObj pt (this->x, this->y);
  88.         
  89.     transform(pt.x, pt.y, gs);
  90.     return b.Contains(pt);
  91. }
  92.  
  93. void Point::SetBrush (PBrush* brush) {
  94.     if (this->brush != Ref(brush)) {
  95.     this->brush = Ref(brush);
  96.     invalidateCaches();
  97.     }
  98. }
  99.  
  100. PBrush* Point::GetBrush () { return (PBrush*) brush(); }
  101.  
  102. boolean Line::read (PFile* f) {
  103.     return Graphic::read(f) && brush.Read(f) &&
  104.     f->Read(x0) && f->Read(y0) && f->Read(x1) && f->Read(y1);
  105. }
  106.  
  107. boolean Line::write (PFile* f) {
  108.     return Graphic::write(f) && brush.Write(f) &&
  109.     f->Write(x0) && f->Write(y0) && f->Write(x1) && f->Write(y1);
  110. }
  111.  
  112. void Line::draw (Canvas* c, Graphic* gs) {
  113.     if (gs->GetBrush()->Width() != NO_WIDTH) {
  114.     update(gs);
  115.     pLine(c, x0, y0, x1, y1);
  116.     }
  117. }
  118.  
  119. ClassId Line::GetClassId () { return _LINE; }
  120. boolean Line::IsA (ClassId id) { return _LINE == id || Graphic::IsA(id); }
  121. Line::Line () {}
  122.  
  123. Line::Line (
  124.     Coord x0, Coord y0, Coord x1, Coord y1, Graphic* gr
  125. ) : Graphic (gr) {
  126.     if (gr == nil) {
  127.     SetBrush(nil);
  128.     } else {
  129.     SetBrush(gr->GetBrush());
  130.     }
  131.     this->x0 = x0;
  132.     this->y0 = y0;
  133.     this->x1 = x1;
  134.     this->y1 = y1;
  135. }
  136.  
  137. Graphic* Line::Copy () { return new Line(x0, y0, x1, y1, this); }
  138.  
  139. void Line::GetOriginal (Coord& x0, Coord& y0, Coord& x1, Coord& y1) {
  140.     x0 = this->x0;
  141.     y0 = this->y0;
  142.     x1 = this->x1;
  143.     y1 = this->y1;
  144. }    
  145.  
  146. void Line::getExtent (
  147.     float& l, float& b, float& cx, float& cy, float& tol, Graphic* gs
  148. ) {
  149.     float r, t, width;
  150.  
  151.     width = float(gs->GetBrush()->Width());
  152.     tol = (width > 1) ? width / 2 : 0;
  153.     
  154.     transform(float(x0+x1)/2, float(y0+y1)/2, cx, cy, gs);
  155.     transform(float(x0), float(y0), l, b, gs);
  156.     transform(float(x1), float(y1), r, t, gs);
  157.     l = min(l, r);
  158.     b = min(b, t);
  159. }
  160.  
  161. boolean Line::contains (PointObj& po, Graphic* gs) {
  162.     LineObj l (x0, y0, x1, y1);
  163.     PointObj pt (&po);
  164.     invTransform(pt.x, pt.y, gs);
  165.     return l.Contains(pt);
  166. }
  167.  
  168. boolean Line::intersects (BoxObj& b, Graphic* gs) {
  169.     LineObj l (this->x0, this->y0, this->x1, this->y1);
  170.     transform(l.p1.x, l.p1.y, gs);
  171.     transform(l.p2.x, l.p2.y, gs);
  172.     return b.Intersects(l);
  173. }
  174.  
  175. void Line::SetBrush (PBrush* brush) {
  176.     if (this->brush != Ref(brush)) {
  177.     this->brush = Ref(brush);
  178.     invalidateCaches();
  179.     }
  180.     this->brush = Ref(brush);
  181. }
  182.  
  183. PBrush* Line::GetBrush () { return (PBrush*) brush(); }
  184. ClassId MultiLine::GetClassId () { return _MULTILINE; }
  185.  
  186. boolean MultiLine::IsA (ClassId id) {
  187.     return _MULTILINE == id || Graphic::IsA(id);
  188. }
  189.  
  190. MultiLine::MultiLine () {
  191.     extent = nil;
  192.     x = y = nil;
  193.     count = 0;
  194. }
  195.  
  196. MultiLine::MultiLine (Coord* x, Coord* y, int count, Graphic* gr) : Graphic (gr) {
  197.     extent = nil;
  198.     if (gr == nil) {
  199.     SetBrush(nil);
  200.     } else {
  201.     SetBrush(gr->GetBrush());
  202.     }
  203.     this->x = new Coord[count];
  204.     this->y = new Coord[count];
  205.     this->count = count;
  206.     CopyArray(x, y, count, this->x, this->y);
  207. }
  208.  
  209. Graphic* MultiLine::Copy () { return new MultiLine(x, y, count, this); }
  210.  
  211. MultiLine::~MultiLine () {
  212.     uncacheExtent();
  213.     delete x; 
  214.     delete y;
  215. }
  216.  
  217. boolean MultiLine::operator == (MultiLine& ml) {
  218.     if (count == ml.count) {
  219.         for (int i = 0; i < count; ++i) {
  220.             if (x[i] != ml.x[i] || y[i] != ml.y[i]) {
  221.                 return false;
  222.             }
  223.         }
  224.         return true;
  225.     }
  226.     return false;
  227. }
  228.  
  229. boolean MultiLine::operator != (MultiLine& ml) { return !(*this == ml); }
  230.  
  231. boolean MultiLine::read (PFile* f) {
  232.     boolean ok = Graphic::read(f) && _patbr.Read(f) && f->Read(count);
  233.     if (ok) {
  234.     delete x;
  235.     delete y;
  236.     x = new Coord [count];
  237.     y = new Coord [count];
  238.     ok = f->Read(x, count) && f->Read(y, count);
  239.     }
  240.     return ok;
  241. }
  242.  
  243. boolean MultiLine::write (PFile* f) {
  244.     return Graphic::write(f) && _patbr.Write(f) && f->Write(count) && 
  245.     f->Write(x, count) && f->Write(y, count);
  246. }
  247.  
  248. boolean MultiLine::extentCached () { return caching && extent != nil; }
  249.  
  250. void MultiLine::uncacheExtent() { 
  251.     delete extent; 
  252.     extent = nil;
  253. }
  254.  
  255. void MultiLine::draw (Canvas *c, Graphic* gs) {
  256.     if (gs->GetBrush()->Width() != NO_WIDTH) {
  257.     update(gs);
  258.     pMultiLine(c, x, y, count);
  259.     }
  260. }
  261.  
  262. void MultiLine::cacheExtent (float l, float b, float cx, float cy, float tol) {
  263.     if (caching) {
  264.     uncacheExtent();
  265.     extent = new Extent(l, b, cx, cy, tol);
  266.     }
  267. }
  268.  
  269. void MultiLine::getCachedExtent (
  270.     float& l, float& b, float& cx, float& cy, float& tol
  271. ) {
  272.     l = extent->left;
  273.     b = extent->bottom;
  274.     cx = extent->cx;
  275.     cy = extent->cy;
  276.     tol = extent->tol;
  277. }
  278.  
  279. void MultiLine::getExtent (
  280.     float& l, float& b, float& cx, float& cy, float& tol, Graphic* gs
  281. ) {
  282.     int i;
  283.     float bx0, by0, bx1, by1, tcx, tcy, width, dummy1, dummy2;
  284.  
  285.     if (extentCached()) {
  286.     getCachedExtent(bx0, by0, tcx, tcy, tol);
  287.     bx1 = 2*tcx - bx0;
  288.     by1 = 2*tcy - by0;
  289.     } else {
  290.     width = float(gs->GetBrush()->Width());
  291.     tol = (width > 1) ? width/2 : 0;
  292.     bx0 = bx1 = x[0]; by0 = by1 = y[0];
  293.     for (i = 1; i < count; ++i) {
  294.         bx0 = min(bx0, float(x[i]));
  295.         by0 = min(by0, float(y[i]));
  296.         bx1 = max(bx1, float(x[i]));
  297.         by1 = max(by1, float(y[i]));
  298.     }
  299.     tcx = (bx0 + bx1) / 2;
  300.     tcy = (by0 + by1) / 2;
  301.     cacheExtent(bx0, by0, tcx, tcy, tol);
  302.     }
  303.     transformRect(bx0, by0, bx1, by1, l, b, dummy1, dummy2, gs);
  304.     transform(tcx, tcy, cx, cy, gs);
  305. }
  306.  
  307. void MultiLine::GetOriginal (Coord*& x, Coord*& y, int& n) {
  308.     n = count;
  309.     x = new Coord[n];
  310.     y = new Coord[n];
  311.     CopyArray(this->x, this->y, count, x, y);
  312. }
  313.  
  314. int MultiLine::GetOriginal (const Coord*& x, const Coord*& y) {
  315.     x = this->x;
  316.     y = this->y;
  317.     return count;
  318. }
  319.  
  320. boolean MultiLine::contains (PointObj& po, Graphic* gs) {
  321.     MultiLineObj ml (x, y, count);
  322.     PointObj pt (&po);
  323.     BoxObj b;
  324.  
  325.     getBox(b, gs);
  326.     if (b.Contains(po)) {
  327.     invTransform(pt.x, pt.y, gs);
  328.     return ml.Contains(pt);
  329.     }
  330.     return false;
  331. }
  332.  
  333. boolean MultiLine::intersects (BoxObj& userb, Graphic* gs) {
  334.     Coord* convx, *convy;
  335.     BoxObj b;
  336.     boolean result = false;
  337.  
  338.     getBox(b, gs);
  339.     if (b.Intersects(userb)) {
  340.     convx = new Coord[count];
  341.     convy = new Coord[count];
  342.     transformList(x, y, count, convx, convy, gs);
  343.     MultiLineObj ml (convx, convy, count);
  344.     result = ml.Intersects(userb);
  345.     delete convx;
  346.     delete convy;
  347.     }
  348.     return result;
  349. }
  350.  
  351. void MultiLine::SetBrush (PBrush* brush) {
  352.     if (br() != Ref(brush)) {
  353.     br(Ref(brush));
  354.     invalidateCaches();
  355.     }
  356. }
  357.  
  358. PBrush* MultiLine::GetBrush () { return (PBrush*) br()(); }
  359. void MultiLine::SetPattern (PPattern* pattern) { pat(Ref(pattern)); }
  360. PPattern* MultiLine::GetPattern () { return (PPattern*) pat()(); }
  361.  
  362. void MultiLine::pat (Ref) { }
  363. Ref MultiLine::pat () { return (MultiLine*)nil; }
  364. void MultiLine::br (Ref r) { _patbr = r; }
  365. Ref MultiLine::br () { return _patbr; }
  366.